package com.example.concurrentprogramming8016.future.forkjoin.arraysum;

import com.example.concurrentprogramming8016.future.forkjoin.ArrayUtils;

import java.util.concurrent.*;

/**
 * @author liyanhao
 * @Date 2023-01-07 23:57
 *
 * 多线程计算1亿个整数的和
 */
public class SumMultiThreads {
    //拆分粒度
    public final static int NUM = 10000000;

    public static long sum(int[] arr, ExecutorService executorService) throws ExecutionException, InterruptedException {
        long result = 0;
        int threadNum = 10;
        SumTask[] sumTasks = new SumTask[threadNum];
        Future<Long>[] sumFuture = new Future[threadNum];
        int avg = arr.length / threadNum;
        for (int i = 0; i < threadNum; i++) {
            sumTasks[i] = new SumTask(arr, avg * i, avg * (i + 1));
            sumFuture[i] = executorService.submit(sumTasks[i]);
        }
        //结果合并
        for (int i = 0; i < threadNum; i++) {
            result += sumFuture[i].get();
        }
        return result;
    }

    public static void main(String[] args) throws Exception {
        int[] arr = ArrayUtils.buildRandomIntArray(1000000000);
        //根据拆分粒度进行计算出需要的线程数
        int numThreads = arr.length / NUM > 0 ? arr.length / NUM : 1;
        long start = System.currentTimeMillis();
        ExecutorService threadPool = Executors.newFixedThreadPool(numThreads);
        long sum = SumMultiThreads.sum(arr, threadPool);
        long end = System.currentTimeMillis();
        System.out.println("操作耗时:" + (end - start));
        System.out.println("计算的结果为:" + sum);
        threadPool.shutdown();
    }
}
